package vacuum.flatgrass;

import java.io.IOException;
import java.util.Random;

import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.java.JavaPlugin;


public class FlatGrass extends JavaPlugin
{

	private FileManager fm;

	CommandExecutor createFG = new CommandExecutor()
	{

		@Override
		public boolean onCommand(CommandSender sender, Command command,
				String label, String[] args)
		{
			if(sender instanceof ConsoleCommandSender){
				System.out.println("Please use this command in-game");
				return true;
			}
			if(sender.hasPermission("vacuum.createFlatgrassMap") || sender.isOp()){
				if(args.length != 1){
					sender.sendMessage("[FlatGrass] Please give a map name.");
					return true;
				}
				String worldName = args[0];
				sender.sendMessage("[FlatGrass] Creating new map " + worldName + "...");
				WorldCreator wc;
				try
				{
					wc = fm.addWorld(worldName, new byte[]{7, 1, 3, 2, 0}, new byte[]{-1, 2, 60, 64, 65});
				} catch (IOException e)
				{
					sender.sendMessage("[FlatGrass] World creation failed!");
					e.printStackTrace();
					return true;
				}
				World w = getServer().createWorld(wc);
				sender.sendMessage("[FlatGrass] Created map " + worldName + ", sending you there now!");
				((Player)sender).teleport(w.getSpawnLocation());
				return true;
			} else
				return false;
		}
	};

	CommandExecutor customFlatmap = new CommandExecutor()
	{

		@Override
		public boolean onCommand(CommandSender sender, Command command,
				String label, String[] args)
		{
			if(sender instanceof ConsoleCommandSender){
				String name = args[0];
				if(args.length % 2 == 0){
					System.out.println("[FlatGrass] Must have an odd number of arguments. Perhaps you forgot the name?");
					return false;
				}
				byte[] heights = new byte[(args.length - 1) / 2];
				byte[] blocks = new byte[(args.length - 1) / 2];
				for (int i = 0; i < blocks.length; i++)
				{
					System.out.println("[FlatGrass] Adding block " + args[i * 2 + 1] + " below height " + args[i * 2 + 2]);
					blocks[i] = Byte.parseByte(args[i * 2 + 1]);
					heights[i] = Byte.parseByte(args[i * 2 + 2]);
				}
				System.out.println("[FlatGrass] Creating world " + name + "...");
				try
				{
					getServer().createWorld(fm.addWorld(name, blocks, heights));
				} catch (Throwable e)
				{
					System.out.println("[FlatGrass] World creation failed!");
					e.printStackTrace();
					return false;
				}
				System.out.println("[FlatGrass] World " + name + " created. Use your world plugin to go there now!");
				getServer().broadcast("World " + name + " created.", Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
				return true;
			}
			return false;
		}
	};

	@Override
	public void onDisable()
	{
		getCommand("createFG").setExecutor(null);
		getCommand("customFlatmap").setExecutor(null);
		getCommand("removeFlatmap").setExecutor(null);
		System.out.println(getName() + " by FalseVacuum disabled");
	}

	@Override
	public void onEnable()
	{
		System.out.println("[FlatGrass] Creating file handler.");
		fm = new FileManager(getDataFolder());

		System.out.println("[FlatGrass] Registering commands.");
		getCommand("createFG").setExecutor(createFG);
		getCommand("customFlatmap").setExecutor(customFlatmap);
		getCommand("removeFlatmap").setExecutor(new CommandExecutor()
		{

			@Override
			public boolean onCommand(CommandSender sender, Command command,
					String label, String[] args)
			{
				if(args.length != 1)
					return false;
				if(sender instanceof Player){
					sender.sendMessage("Please use the console for this command");
					return true;
				}
				args[0] = getServer().getWorld(args[0]).getName();
				try
				{
					if(fm.removeWorld(args[0])){
						getServer().unloadWorld(args[0], false);
						for (int i = 0; i < args.length; i++)
						{

						}
					}
				} catch (IOException e)
				{
					e.printStackTrace();
				}
				return true;
			}
		});

		System.out.println("[FlatGrass] Loading worlds.");
		try {
			for(WorldCreator wc : fm.loadWorlds()){
				System.out.println("[FlatGrass] Creating new world: " + wc.name());
				getServer().createWorld(wc);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println(getFullName() + " by FalseVacuum enabled");
	}

	private String getFullName(){
		return "FlatGrass" + getDescription().getVersion();
	}

	static ChunkGenerator getGenerator(final byte[] blocks, final byte[] heights)
	{
		return new ChunkGenerator()
		{

			@Override
			public byte[] generate(World arg0, Random rand, int xPos, int zPos)
			{
				final byte[] worldData = new byte[32768];
				for (int x = 0; x < 16; x++) {
					for (int z = 0; z < 16; z++) {
						for (int y = 0; y < 128; y++) {
							byte item = 0;
							for (int i = 0; i < heights.length; i++)
							{
								if(heights[i] > y){
									item = blocks[i];
									break;
								}
							}
							worldData[(x * 16 + z) * 128 + y] = item;
						}
					}
				}
				return worldData;
			}
		};
	}
}